/**
 * 
 */
package jvs.vfs.opt;

import java.net.URI;

import jvs.vfs.FileSystem;
import x.java.io.File;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public final class OpenVFS {

	private static final FileSystem fs = FileSystem.getFileSystem();

	private static final String LOG_TAG = "OpenVFS";

	private static final String OPENVFS_LOCATION = "openvfs";

	private static boolean DEBUG = FileSystem.DEBUG;

	private static boolean running = false;

	private static boolean sdcardAvailable() {
		return android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED);
	}

	synchronized public static void boot(Context ctx) {
		if (DEBUG) {
			Log.d(LOG_TAG, "boot running: " + running);
		}
		if (running) {
			return;
		}
		final long start = System.currentTimeMillis();
		//
		final String uri = "jfs:resource:/jvs/vfs/opt/root.xml!/";

		try {
			jvs.OS.name = "Hotweb 1.0.0";
			jvs.OS.version = "v1.0.0";
			jvs.OS.copyright = "Copyright &copy; Li, Qiang 2010, all rights reserved.";
			jvs.OS.applink = "v:///";

			java.lang.System.setProperty("jvs.rootfs", uri);
			// java.lang.System.setProperty("jvs.debug", DEBUG_JVS);
			//
			fs.setContext(ctx);

			fs.boot(uri);

			//register
			fs.registerProvider("asset", "jvs.vfs.opt.asset.AssetFileImpl");
			fs.registerProvider("media", "jvs.vfs.opt.media.MediaFileImpl");
			// fs.registerProvider("music", "jvs.vfs.opt.media.MusicFileImpl");
			fs.registerProvider("app", "jvs.vfs.opt.app.AppFileImpl");
			fs.registerProvider("email",
					"jvs.vfs.opt.contact.EmailContactFileImpl");
			fs.registerProvider("phone",
					"jvs.vfs.opt.contact.PhoneContactFileImpl");
			fs.registerProvider("bookmark",
					"jvs.vfs.opt.browse.BookmarkFileImpl");
			//fs.registerProvider("home", "jvs.vfs.opt.home.LauncherFileImpl");
			fs.registerProvider("call", "jvs.vfs.opt.contact.CallLogFileImpl");
			
			//mount
			java.io.File root = getSystemRoot();
			java.io.File loc = new java.io.File(root, OPENVFS_LOCATION);
			//
			fs.mount("/application/", new URI("app:/"), "r");
			fs.mount("/android/", new URI("file:/"), "r");
			fs.mount("/sdcard/", root.toURI(), "rw");
			fs.mount("/temp/", ensureURI(loc, "temp"), "rw");
			//
			fs.mount("/my/bookmark", new URI("bookmark:/"), "r");
			//fs.mount("/my/call", new URI("call:/"), "r");
			//fs.mount("/my/contact/email/", new URI("email:/"), "r");
			//fs.mount("/my/contact/phone/", new URI("phone:/"), "r");
			fs.mount("/my/media/", new URI("media:/"), "r");
			//
			fs.mount("/system/proc", new URI("proc:/"), "r");
			//
			//
			
			//fs.mount("/my/doc", ensureURI(loc, "doc"), "rw");
			//fs.mount("/home", new URI("home:/"), "r");
			
			//
			Intent i = new Intent();
			i.setAction(jvs.vfs.opt.Intents.ACTION_VFS_MOUNT_COMPLETED);
			ctx.sendBroadcast(i);
			//
			//
			cleanup();
		} catch (Exception e) {
			e.printStackTrace();
		}

		long end = System.currentTimeMillis();
		//
		running = true;
		if (DEBUG) {
			Log.d(LOG_TAG, "boot succeeded. jvs.rootfs: " + uri + " in "
					+ (end - start) + " ms");
		}
	}

	private static URI ensureURI(java.io.File loc, String name) {
		java.io.File f = new java.io.File(loc, name);
		URI uri = f.toURI();
		try {
			if (!f.exists()) {
				f.mkdirs();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return uri;
	}

	private static void cleanup() {
		try {
			if (sdcardAvailable()) {
				java.io.File f = File.getLocalTempDirectory();
				File.cleanupTempDirectory();
				if (DEBUG) {
					Log.d(LOG_TAG, "cleaning up temp files in " + f);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static java.io.File getSystemRoot() {
		return Environment.getExternalStorageDirectory();
	}

	synchronized public static void halt() {
		running = false;
	}

	public static void init(final Context ctx) {
		if (DEBUG) {
			Log.d(LOG_TAG, "init: " + ctx);
		}
		Runnable r = new Runnable() {
			public void run() {
				try {
					boot(ctx);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		new Thread(r).start();
	}

	public static boolean isRunning() {
		return running;
	}

	private OpenVFS() {
	}

}